#pragma once
#include "crypto/padding/Padding.h"
#include "array/Arrays.h"
#include "lang/System.h"

namespace yzrilyzr_crypto{
	ECLASS(PKCS7Padding, public Padding){
	public:
	PKCS7Padding()=default;

	/* PKCS7填充 */
	yzrilyzr_array::ByteArray padding(const yzrilyzr_array::ByteArray & in,
										u_index off,
										u_index len,
										u_index paddingLen) override{
		return pkcs7Padding(in, off, len, paddingLen);
	}

	/* PKCS7去填充 */
	u_index unpadding(const yzrilyzr_array::ByteArray & in) override{
		return PKCS7Unpadding(in);
	}

	/* 静态PKCS7去填充方法 */
	static u_index PKCS7Unpadding(const yzrilyzr_array::ByteArray & in){
		int n=in[in.length - 1];
		// 检查填充字节数是否有效
		if(n > in.length || n <= 0){
			return in.length;
		}

		// 验证所有填充字节是否正确
		for(u_index i=in.length - n; i < in.length; i++){
			if(in[i] != n){
				return in.length; // 填充无效，返回原始长度
			}
		}

		return in.length - n; // 返回实际数据长度
	}

	/* 静态PKCS7填充方法 */
	static yzrilyzr_array::ByteArray pkcs7Padding(const yzrilyzr_array::ByteArray & in,
													u_index off,
													u_index len,
													u_index paddingLen){
		  // 如果需要填充的长度大于当前数据长度
		if(paddingLen > len){
			if(paddingLen == in.length){
				// 如果目标长度等于输入数组长度，在原数组上操作
				if(off > 0){
					// 如果有偏移，先移动数据到数组开头
					yzrilyzr_lang::System::arraycopy(in, off, const_cast<yzrilyzr_array::ByteArray &>(in), 0, len);
				}

				// 计算需要填充的字节数
				u_index n=paddingLen - len;

				// 填充字节
				for(u_index i=len; i < paddingLen; i++){
					const_cast<yzrilyzr_array::ByteArray &>(in)[i]=static_cast<int8_t>(n);
				}

				return const_cast<yzrilyzr_array::ByteArray &>(in);
			} else{
				// 创建新数组
				static yzrilyzr_array::ByteArray result;
				result=yzrilyzr_array::ByteArray(paddingLen);

				// 拷贝原始数据
				yzrilyzr_lang::System::arraycopy(in, off, result, 0, len);

				// 计算需要填充的字节数
				u_index n=paddingLen - len;

				// 填充字节
				for(u_index i=len; i < paddingLen; i++){
					result[i]=static_cast<int8_t>(n);
				}

				return result;
			}
		} else if(paddingLen == len){
			// 长度正好，不需要填充
			return const_cast<yzrilyzr_array::ByteArray &>(in);
		}

		// 如果paddingLen < len，抛出异常
		throw yzrilyzr_lang::IndexOutOfBoundsException("Padding length is less than data length");
	}

	};
}